#ifndef __MYLOGGER_H__
#define __MYLOGGER_H__

#include <iostream>
#include <string>
#include <log4cpp/Category.hh>

using std::cout;
using std::endl;
using std::string;
using std::to_string;

using namespace log4cpp;

//单例模式的特点：一个类只能创建一个对象
class Mylogger
{
public:
    static Mylogger *getInstance();
    static void destroy();

    template <typename ...Args>
	void warn(const char *msg, Args ...args)
    {
        _root.warn(msg, args...);
    }

    template <typename ...Args>
	void error(const char *msg, Args ...args)
    {
        _root.error(msg, args...);
    }

    template <typename ...Args>
	void debug(const char *msg, Args ... args)
    {
        _root.debug(msg, args...);
    }

    template <typename ...Args>
	void info(const char *msg, Args ...args)
    {
        _root.info(msg, args...);
    }

	void warn(const char *msg);
	void error(const char *msg);
	void debug(const char *msg);
	void info(const char *msg);

private:
	Mylogger();
	~Mylogger();

private:
    static Mylogger *_pInstance;
    Category &_root;//日志记录器是唯一的
};

//带参数的宏定义
#define prefix(msg) (string(__FILE__) + string(": ") \
                 + string(__FUNCTION__) + string(": ") \
                 + string(to_string(__LINE__)) + string(": ") \
                 + msg).c_str()
    
//__VA_ARGS__宏可以解决...的问题，但是如果参数是0个的话，那么
//...前面的逗号是消除不了的，所以使用的##
#define logError(msg, ...) \
    Mylogger::getInstance()->error(prefix(msg), ##__VA_ARGS__)

#define logInfo(msg, ...) \
    Mylogger::getInstance()->info(prefix(msg), ##__VA_ARGS__)

#define logWarn(msg, ...) \
    Mylogger::getInstance()->warn(prefix(msg), ##__VA_ARGS__)

#define logDebug(msg, ...) \
    Mylogger::getInstance()->debug(prefix(msg), ##__VA_ARGS__)

#endif
